home *** CD-ROM | disk | FTP | other *** search
- /*
- File: Windows.c
-
- Contains: Handle application's windows
-
- Written by: Chris White, Developer Technical Support
-
- Copyright: © 1996 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- 03/29/96 CW First release
-
- */
-
-
- #pragma segment Core
-
-
-
- // System Includes
-
- #ifndef __TYPES__
- #include <Types.h>
- #endif
-
- #ifndef __WINDOWS__
- #include <Windows.h>
- #endif
-
- #ifndef __DIALOGS__
- #include <Dialogs.h>
- #endif
-
- #ifndef __QUICKDRAW__
- #include <Quickdraw.h>
- #endif
-
- #ifndef __PICTUTILS__
- #include <PictUtils.h>
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifndef __FONTS__
- #include <Fonts.h>
- #endif
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
-
-
-
- // Application Includes
-
- #ifndef __BAREBONES__
- #include "BareBones.h"
- #endif
-
- #ifndef __PROTOTYPES__
- #include "Prototypes.h"
- #endif
-
-
-
-
- // Static prototypes
- static OSErr CreateDocumentWindow ( WindowRef* windowRef );
- static GWorldPtr CreateOffscreen ( CTabHandle theCTabHndl, SInt16 theXsize, SInt16 theYsize,
- SInt16 theBitDepth, GWorldFlags theFlags );
- static OSErr DrawPictToOffscreen ( PicHandle thePictHndl, GWorldPtr theOffscreen );
- static OSErr DrawOffscreenToWindow ( GWorldPtr theOffscreen, WindowPtr theWindow );
- static Rect GetWindowVisibleRect ( WindowRef theWindow, SInt16 theSizeX, SInt16 theSizeY );
- static void SaveSetMMUMode ( Boolean bIsSaveMode );
- static void DrawClippedScrollBarLines ( WindowRef theWindow );
- static void DrawClippedGrowIcon ( WindowRef theWindow );
- static void HandleContentClick ( WindowRef theWindow, EventRecord* event );
- static OSErr CreateWindowInfo ( WindowRef windowRef, Size infoSize );
- static pascal OSErr SafeGetPictInfo ( PicHandle thePictHandle, PictInfo* thePictInfo,
- SInt16 verb, SInt16 colorsRequested,
- SInt16 colorPickMethod, SInt16 version );
- static void SizeScrollBars ( WindowRef theWindow );
- static Point GetMaximumWindowSize ( WindowRef theWindow );
-
-
-
- // Default RGB Colors
-
- static const RGBColor kRGBBlack = {0x0000, 0x0000, 0x0000};
- static const RGBColor kRGBWhite = {0xFFFF, 0xFFFF, 0xFFFF};
-
-
-
-
-
-
- //
- // This is called to create the application's window.
- //
- void CreateWindow ( void )
- {
- OSErr theErr;
- WindowRef theWindow;
-
- theErr = CreateDocumentWindow ( &theWindow );
- if ( theErr )
- AlertUser ( kGenericErrorStr, theErr, "\p" );
-
- return;
- }
-
-
-
- //
- // This will close the application's window, dispose of any storage we've hung
- // off the window, and then dispose of the window itself.
- //
- WindowRef DestroyWindow ( WindowRef windowRef )
- {
- if ( windowRef )
- {
- tWindowInfoPtr theInfo;
-
- theInfo = (tWindowInfoPtr) GetWRefCon ( windowRef );
- if ( theInfo )
- {
- if ( theInfo->hScrollBar )
- DisposeControl ( theInfo->hScrollBar );
- if ( theInfo->vScrollBar )
- DisposeControl ( theInfo->vScrollBar );
-
- if ( theInfo->offscreen )
- DisposeGWorld ( theInfo->offscreen );
-
- DisposePtr ( (Ptr) theInfo );
- }
-
- DisposeWindow ( windowRef );
-
- }
-
- return nil;
- }
-
-
-
- void DoActivate ( EventRecord* theEvent )
- {
- Boolean bActiveFlag = theEvent->modifiers & resumeFlag;
- WindowRef theWindow = (WindowRef) theEvent->message;
- GrafPtr savePort;
- tWindowInfoPtr theInfo;
-
-
- gInBackground = (theEvent->modifiers & resumeFlag) == 0;
-
- GetPort ( &savePort );
- SetPortWindowPort ( theWindow );
-
- theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow );
-
- if ( bActiveFlag )
- {
- ShowControl ( theInfo->hScrollBar );
- ShowControl ( theInfo->vScrollBar );
- }
- else
- {
- HideControl ( theInfo->hScrollBar );
- HideControl ( theInfo->vScrollBar );
- DrawClippedScrollBarLines ( theWindow );
- }
-
- DrawClippedGrowIcon ( theWindow );
-
- SetPort ( savePort );
-
- return;
- }
-
-
-
- void DoUpdate ( WindowRef theWindow )
- {
- GrafPtr savePort;
- CGrafPtr thePort;
-
-
- thePort = GetWindowPort ( theWindow );
-
- GetPort ( &savePort );
- SetPortWindowPort ( theWindow );
- BeginUpdate ( theWindow ); // visRgn temporarily = updateRgn
- EraseRect ( &thePort->portRect );
-
- UpdateWindowContent ( theWindow );
-
- if ( gInBackground )
- DrawClippedScrollBarLines ( theWindow );
- else
- UpdateControls ( theWindow, theWindow->visRgn );
- DrawClippedGrowIcon ( theWindow );
-
- EndUpdate ( theWindow ); // restore normal visRgn of grafport
- SetPort ( savePort );
-
- return;
- }
-
-
-
- void UpdateWindowContent ( WindowRef theWindow )
- {
- tWindowInfoPtr theInfo;
-
- theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow );
- DrawOffscreenToWindow ( theInfo->offscreen, theWindow );
-
- return;
- }
-
-
-
- void DoContentClick ( WindowRef theWindow, EventRecord* theEvent )
- {
- OSErr theErr = noErr;
- WindowRef frontWindow;
-
- // If a movable modal is active, ignore click in an inactive
- // window, otherwise select it or handle the content click.
-
- frontWindow = FrontWindow ( );
- if ( theWindow != frontWindow )
- {
- if ( IsMovableModal ( frontWindow ) )
- SysBeep ( 30 );
- else
- SelectWindow ( theWindow );
- }
- else
- {
- SInt16 thePart;
- GrafPtr savePort;
- ControlRef theControl;
- Point localPt;
-
- localPt = theEvent->where;
- GlobalToLocal ( &localPt );
- thePart = FindControl ( localPt, theWindow, &theControl );
-
- GetPort ( &savePort );
- SetPortWindowPort ( theWindow );
-
- if ( thePart )
- {
- switch ( thePart )
- {
- case inUpButton:
- case inDownButton:
- case inPageUp:
- case inPageDown:
- TrackControl ( theControl, localPt, gScrollControlActionUPP );
- break;
-
- case inThumb:
- if ( BeginThumbTracking ( theControl ) == noErr )
- {
- TrackControl ( theControl, localPt,
- (ControlActionUPP) gScrollThumbActionUPP );
- EndThumbTracking ( );
- }
- break;
- }
- }
- else
- HandleContentClick ( theWindow, theEvent );
-
- SetPort ( savePort );
- }
-
- return;
-
- } // DoContentClick
-
-
-
- void DoGrowWindow ( WindowRef theWindow, EventRecord* theEvent )
- {
- WindowPtr savePort;
- SInt32 returnCoord;
- Rect resizeBounds;
- SInt16 theWidth,
- theHeight;
- Point theMaxSize;
-
- GetPort ( &savePort );
- theMaxSize = GetMaximumWindowSize ( theWindow );
- SetRect ( &resizeBounds, 96, 96, theMaxSize.h, theMaxSize.v );
- returnCoord = GrowWindow ( theWindow, theEvent->where, &resizeBounds );
- theHeight = HiWord ( returnCoord );
- theWidth = LoWord ( returnCoord );
-
- SizeWindow ( theWindow, theWidth, theHeight, true );
- SizeScrollBars ( theWindow );
- SetPort ( theWindow );
- InvalRect ( &theWindow->portRect );
-
- SetPort ( savePort );
-
-
- return;
- }
-
-
-
- void DoDragWindow ( WindowRef theWindow, EventRecord* theEvent )
- {
- WindowRef frontWindow;
-
-
- // If a movable modal is active, ignore click in an inactive
- // title bar, otherwise let the Window Manager handle it.
-
- frontWindow = FrontWindow ( );
- if ( theWindow != frontWindow && IsMovableModal ( frontWindow ) )
- SysBeep ( 30 );
- else
- {
- RgnHandle theRgn;
- Rect dragRect;
-
- theRgn = GetGrayRgn ( );
- dragRect = (*theRgn)->rgnBBox;
- DragWindow ( theWindow, theEvent->where, &dragRect );
- }
-
- return;
- }
-
-
-
- OSErr DoAboutBox ( void )
- {
-
- OSErr theErr = noErr;
- SInt16 theItem = 0;
- GrafPtr savePort = nil;
- DialogRef theDialog;
- ModalFilterUPP theFilter = nil;
-
-
- theDialog = GetNewDialog ( kAboutDialog, nil, (WindowPtr) -1 );
-
- GetPort ( &savePort );
- SetPort ( theDialog );
-
- ShowWindow ( theDialog );
-
- // Get the standard filter proc
- theErr = GetStdFilterProc ( &theFilter );
- if ( theErr )
- goto CleanupAndBail;
-
- // Tell the dialog manager to use the default button
- SetDialogDefaultItem ( theDialog, kStdOkItemIndex );
-
-
- // Modal dialog loop
- do
- {
- // Use "theFilter" in ModalDialog call
- ModalDialog ( theFilter, &theItem );
-
- } while ( theItem != kStdOkItemIndex );
-
-
- CleanupAndBail:
-
- DisposeDialog ( theDialog );
- SetPort ( savePort );
-
- return theErr;
- }
-
-
-
- //
- // Creates a document window containing a picture.
- //
- static OSErr CreateDocumentWindow ( WindowRef* windowRef )
- {
- OSErr theErr = noErr;
- WindowRef theWindow;
- Point theImageSize;
- PicHandle thePict = nil;
- PictInfo thePictInfo;
- tWindowInfoPtr theInfo;
-
-
-
- theWindow = GetNewCWindow ( kDisplayWindow, nil, (WindowRef) -1 );
- if ( theWindow == nil )
- return (ResError ( )) ? ResError ( ) : resNotFound;
-
- theErr = CreateWindowInfo ( theWindow, sizeof ( tWindowInfo ) );
- if ( theErr ) goto CleanupAndBail;
-
- theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow );
-
- SetPortWindowPort ( theWindow );
-
- thePict = GetPicture ( kPictureID );
- if ( thePict == nil ) goto CleanupAndBail;
-
- theErr = SafeGetPictInfo ( thePict, &thePictInfo, returnColorTable, 256, systemMethod, 0 );
- if ( theErr ) goto CleanupAndBail;
-
- theImageSize.h = thePictInfo.sourceRect.right - thePictInfo.sourceRect.left;
- theImageSize.v = thePictInfo.sourceRect.bottom - thePictInfo.sourceRect.top;
-
- theInfo->offscreen = CreateOffscreen ( (thePictInfo.depth <= 8) ? thePictInfo.theColorTable : nil,
- theImageSize.h, theImageSize.v, thePictInfo.depth,
- kNoFlags );
- if ( theInfo->offscreen == nil ) goto CleanupAndBail;
-
- theInfo->hScrollBar = GetNewControl ( kScrollBar, theWindow );
- theInfo->vScrollBar = GetNewControl ( kScrollBar, theWindow );
- if ( theInfo->hScrollBar == nil || theInfo->vScrollBar == nil)
- goto CleanupAndBail;
-
-
- // Setup the correct control values
- SetControlMinimum ( theInfo->hScrollBar, 0 );
- SetControlMinimum ( theInfo->vScrollBar, 0 );
- SetControlValue ( theInfo->hScrollBar, 0 );
- SetControlValue ( theInfo->vScrollBar, 0 );
-
- SizeScrollBars ( theWindow );
-
- theErr = DrawPictToOffscreen ( thePict, theInfo->offscreen );
- if ( theErr ) goto CleanupAndBail;
-
- SelectWindow ( theWindow );
- ShowWindow ( theWindow );
-
- *windowRef = theWindow;
-
- if ( thePict )
- ReleaseResource ( (Handle) thePict );
-
- return noErr;
-
- CleanupAndBail:
-
- // Don't forget to free any storage we've used so far
- if ( thePict )
- ReleaseResource ( (Handle) thePict );
-
- DestroyWindow ( theWindow );
-
- return theErr;
- }
-
-
-
- static GWorldPtr CreateOffscreen ( CTabHandle theCTabHndl, SInt16 theXsize, SInt16 theYsize,
- SInt16 theBitDepth, GWorldFlags theFlags )
- {
- GWorldPtr theGWorld = nil;
- QDErr theErr;
- Rect theRect;
-
-
- SetRect ( &theRect, 0, 0, theXsize, theYsize );
- theErr = NewGWorld ( &theGWorld, theBitDepth, &theRect, theCTabHndl, nil, theFlags );
-
- #if WARNINGS
- if ( theErr )
- DebugStrNum ( "\p CreateOffscreen: ", theErr );
- #endif
-
- return theGWorld;
- }
-
-
-
- static OSErr DrawPictToOffscreen ( PicHandle thePictHndl, GWorldPtr theOffscreen )
- {
- PixMapHandle theGWorldPMHndl;
- GDHandle saveGDevice;
- CGrafPtr saveGWorld;
- OSErr theErr = noErr;
-
-
- GetGWorld ( &saveGWorld, &saveGDevice );
- SetGWorld ( theOffscreen, nil );
-
- // We'll initialize out port settings here.
- // If you don't set the foreground and background colors to black
- // and white, colorisation can occur during the call to CopyBits.
- RGBForeColor ( &kRGBBlack );
- RGBBackColor ( &kRGBWhite );
- // Reset the transfer mode
- PenMode ( srcCopy );
-
-
- theGWorldPMHndl = GetGWorldPixMap ( theOffscreen );
- LockPixels ( theGWorldPMHndl );
-
- EraseRect ( &theOffscreen->portRect );
- // render the image into the offscreen buffer
- HLock ( (Handle) thePictHndl );
- DrawPicture ( thePictHndl, &theOffscreen->portRect );
- HUnlock ( (Handle) thePictHndl );
-
- UnlockPixels ( theGWorldPMHndl );
- SetGWorld ( saveGWorld, saveGDevice );
-
- return theErr;
- }
-
-
-
- static OSErr DrawOffscreenToWindow ( GWorldPtr theOffscreen, WindowPtr theWindow )
- {
- OSErr theErr = noErr;
- CGrafPtr savePort = nil;
- GDHandle saveGDevice;
- PixMapHandle thePixMapHndl = nil;
- RGBColor saveForeColor,
- saveBackColor;
- Rect sourceRect,
- destRect;
-
-
- GetGWorld ( &savePort, &saveGDevice );
- SetGWorld ( theOffscreen, nil );
- GetForeColor ( &saveForeColor );
- GetBackColor ( &saveBackColor );
-
- RGBForeColor ( &kRGBBlack );
- RGBBackColor ( &kRGBWhite );
- thePixMapHndl = GetGWorldPixMap ( theOffscreen );
- if ( PixMap32Bit ( thePixMapHndl ) ) // if 32bit mode needed == true
- SaveSetMMUMode ( true );
- if ( !LockPixels ( thePixMapHndl ) )
- goto CleanupAndBail;
-
- sourceRect = theOffscreen->portRect;
- destRect = theWindow->portRect;
- destRect.right -= kScrollBarWidth; // exclude scrollbar area
- destRect.bottom -= kScrollBarWidth;
- if ( !EqualRect ( &sourceRect, &destRect ) )
- sourceRect = GetWindowVisibleRect ( theWindow, destRect.right, destRect.bottom );
- SetGWorld ( savePort, saveGDevice );
- savePort = nil;
-
- CopyBits ( (BitMap*) *thePixMapHndl, (BitMap*) &theWindow->portBits,
- &sourceRect, &destRect, srcCopy, nil);
-
-
- CleanupAndBail:
-
- if ( savePort )
- SetGWorld ( savePort, saveGDevice );
-
- RGBForeColor ( &saveForeColor );
- RGBBackColor ( &saveBackColor );
- UnlockPixels ( thePixMapHndl );
- SaveSetMMUMode ( false );
-
- return theErr;
- }
-
-
-
- static void DrawClippedScrollBarLines ( WindowRef theWindow )
- {
- CGrafPtr thePort;
- Rect theRect;
-
-
- thePort = GetWindowPort ( theWindow );
- theRect = thePort->portRect;
-
- MoveTo ( theRect.left, theRect.bottom - kScrollBarWidthAdjust );
- LineTo ( theRect.right - kScrollBarWidthAdjust, theRect.bottom - kScrollBarWidthAdjust );
- MoveTo ( theRect.right - kScrollBarWidthAdjust, theRect.top );
- LineTo ( theRect.right - kScrollBarWidthAdjust, theRect.bottom - kScrollBarWidthAdjust );
-
- return;
- }
-
-
-
- static void DrawClippedGrowIcon ( WindowRef theWindow )
- {
- CGrafPtr thePort;
- RgnHandle saveClip = nil;
- Rect newClip;
-
-
- thePort = GetWindowPort ( theWindow );
- saveClip = NewRgn ( );
- GetClip ( saveClip );
-
- newClip = thePort->portRect;
- newClip.top = newClip.bottom - kScrollBarWidth;
- newClip.left = newClip.right - kScrollBarWidth;
- ClipRect ( &newClip );
- DrawGrowIcon ( theWindow );
-
- SetClip ( saveClip );
- DisposeRgn ( saveClip );
-
- return;
- }
-
-
-
- static Rect GetWindowVisibleRect ( WindowRef theWindow, SInt16 theSizeX, SInt16 theSizeY )
- {
- Rect displayRect;
- SInt16 theValueX,
- theValueY;
- tWindowInfoPtr theInfo;
-
- theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow );
- theValueX = GetControlValue ( theInfo->hScrollBar );
- theValueY = GetControlValue ( theInfo->vScrollBar );
- SetRect ( &displayRect, theValueX, theValueY, theValueX + theSizeX, theValueY + theSizeY );
-
- return displayRect;
- }
-
-
-
- static void SaveSetMMUMode ( Boolean bIsSaveMode )
- {
- static signed char theAddrMode = true32b;
- static Boolean bSwapModeNeeded = false;
-
- if ( bIsSaveMode )
- {
- if ( GetMMUMode ( ) == false32b ) // get current addr mode
- {
- bSwapModeNeeded = true; // in 24 bit mode swap needed
- SwapMMUMode ( &theAddrMode ); // switch to 32 bit mode
- }
- }
- else if ( bSwapModeNeeded )
- SwapMMUMode ( &theAddrMode );
-
- return;
- }
-
-
-
- static void HandleContentClick ( WindowRef theWindow, EventRecord* event )
- {
- Point localPt;
-
- localPt = event->where;
- GlobalToLocal ( &localPt );
-
- // Handle any content clicks here
-
- return;
- }
-
-
-
- //
- // Creates the storage for the data to hang off a window or dialog
- //
- static OSErr CreateWindowInfo ( WindowRef windowRef, Size infoSize )
- {
- OSErr theErr;
- Ptr theInfo = nil;
-
-
- theInfo = NewPtrClear ( infoSize );
- theErr = MemError ( );
- if ( theErr )
- return theErr;
-
- SetWRefCon ( windowRef, (long) theInfo );
-
- return noErr;
- }
-
-
-
- //
- // The GetPictInfo routine has a bug which will allow all hell to
- // break loose if there isn't enough temporary memory available.
- //
- static pascal OSErr SafeGetPictInfo ( PicHandle thePictHandle, PictInfo* thePictInfo, SInt16 verb, SInt16 colorsRequested, SInt16 colorPickMethod, SInt16 version )
- {
- const SInt32 kMinLowMem = 10240; // 10K isn't too much to ask for!
-
- if ( TempFreeMem ( ) < kMinLowMem )
- return memFullErr;
-
- return GetPictInfo ( thePictHandle, thePictInfo, verb, colorsRequested, colorPickMethod, version );
- }
-
-
-
- static void SizeScrollBars ( WindowRef theWindow )
- {
- SInt16 maxXsize,
- maxYsize;
- tWindowInfoPtr theInfo;
-
-
- theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow );
-
- MoveControl ( theInfo->vScrollBar, theWindow->portRect.right - kScrollBarWidthAdjust,
- theWindow->portRect.top - 1 );
- MoveControl ( theInfo->hScrollBar, theWindow->portRect.left - 1,
- theWindow->portRect.bottom - kScrollBarWidthAdjust );
- SizeControl ( theInfo->vScrollBar, kScrollBarWidth,
- theWindow->portRect.bottom - theWindow->portRect.top - 13 );
- SizeControl ( theInfo->hScrollBar, theWindow->portRect.right - theWindow->portRect.left - 13,
- kScrollBarWidth );
-
- maxXsize = theInfo->offscreen->portRect.right -
- ((theWindow->portRect.right - kScrollBarWidthAdjust) - theWindow->portRect.left);
- maxYsize = theInfo->offscreen->portRect.bottom -
- ((theWindow->portRect.bottom - kScrollBarWidthAdjust) - theWindow->portRect.top);
- SetControlMaximum ( theInfo->vScrollBar, maxYsize );
- SetControlMaximum ( theInfo->hScrollBar, maxXsize );
-
- return;
- }
-
-
-
- //
- // Calculates the maximum window size based on the image size and the
- // current size of the main screen. The image size is used, but resticted
- // by the current screen size.
- //
- static Point GetMaximumWindowSize ( WindowRef theWindow )
- {
- GDHandle theMainGDevHndl;
- Point theWindowSize,
- theImageSize;
- tWindowInfoPtr theInfo;
-
-
- theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow );
-
- // Calulate the image size
- theImageSize.h = theInfo->offscreen->portRect.right - theInfo->offscreen->portRect.left;
- theImageSize.v = theInfo->offscreen->portRect.bottom - theInfo->offscreen->portRect.top;
- theImageSize.h += kScrollBarWidth;
- theImageSize.v += kScrollBarWidth;
-
- // Calulate the screen size
- theMainGDevHndl = GetMainDevice ( );
- theWindowSize.h = (*theMainGDevHndl)->gdRect.right - (*theMainGDevHndl)->gdRect.left;
- theWindowSize.v = (*theMainGDevHndl)->gdRect.bottom - (*theMainGDevHndl)->gdRect.top;
- theWindowSize.v -= GetMBarHeight ( );
-
- // Make sure the image size is within the constraints of the screen
- theWindowSize.h = theWindowSize.h < theImageSize.h ? theWindowSize.h : theImageSize.h;
- theWindowSize.v = theWindowSize.v < theImageSize.v ? theWindowSize.v : theImageSize.v;
-
- return theWindowSize;
- }
-
-
-
-
-
-
-
-